package com.csg.boot.starter.constant;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.Ordered;
import org.springframework.web.bind.annotation.RequestMethod;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.*;

import java.util.*;

/**
 * @author george
 */
@Data
@ConfigurationProperties("swagger")
public class SwaggerProperties {

    private Boolean enabled = true;

    private UiConfigProperties uiConfig = new UiConfigProperties();

    private DocketProperties docket = new DocketProperties();

    private Map<String, DocketProperties> dockets = new LinkedHashMap<>();

    @Data
    public static class UiConfigProperties {

        private Boolean deepLinking = true;
        private Boolean displayOperationId = false;
        private Integer defaultModelsExpandDepth = 1;
        private Integer defaultModelExpandDepth = 1;
        private ModelRendering defaultModelRendering = ModelRendering.EXAMPLE;
        private Boolean displayRequestDuration = false;
        private DocExpansion docExpansion = DocExpansion.NONE;
        private Object filter = false;
        private Integer maxDisplayedTags = null;
        private OperationsSorter operationsSorter = OperationsSorter.ALPHA;
        private Boolean showExtensions = false;
        private TagsSorter tagsSorter = TagsSorter.ALPHA;

        private String[] supportedSubmitMethods = UiConfiguration.Constants.DEFAULT_SUBMIT_METHODS;
        private String validatorUrl = null;
    }

    @Data
    public static class ResponseMessageProperties {

        /**
         * 响应码
         **/
        private int code;

        /**
         * 响应消息
         **/
        private String message;

        /**
         * 响应体
         **/
        private String modelRef;
    }

    @Data
    public static class ParametersProperties {

        private String name;

        private String description;

        private String defaultValue;

        private Boolean required;

        private String paramType;

        private String paramAccess;

        private String modelRef;

        private Boolean hidden;

        private String pattern;

        private String collectionFormat = null;

        private Boolean allowEmptyValue;

        private Integer order = Ordered.LOWEST_PRECEDENCE;
    }

    @Data
    public static class DocketProperties {

        /**
         * swagger会解析的url规则
         */
        private String path = "/";

        /**
         * swagger会解析的包路径
         */
        private String basePackage = "com.csg";

        /**
         * Api信息
         */
        private ApiInfoProperties apiInfo = new ApiInfoProperties();

        private Boolean forCodeGen = false;

        private Boolean externallyConfiguredFlag = true;

        private Boolean applyDefaultResponseMessages = true;

        private String groupName = Docket.DEFAULT_GROUP_NAME;

        private SecurityProperties security = new SecurityProperties();

        private List<ParametersProperties> globalOperationParameters;

        private Set<Class> ignorableParameterTypes = new HashSet<>();

        private Map<RequestMethod, List<ResponseMessageProperties>> responseMessages = new EnumMap<>(RequestMethod.class);
    }

    @Data
    public static class ContactProperties {

        /**
         * 联系人
         */
        private String name = ApiInfo.DEFAULT_CONTACT.getName();

        /**
         * 联系人url
         */
        private String url = ApiInfo.DEFAULT_CONTACT.getUrl();

        /**
         * 联系人email
         */
        private String email = ApiInfo.DEFAULT_CONTACT.getEmail();
    }

    @Data
    public static class SecurityProperties {

        /**
         * 鉴权策略，可选 apiKey | basicAuth | oauth2，默认ApiKey
         */
        private SecurityEnum type = SecurityEnum.API_KEY;

        /**
         * 鉴权策略ID，对应 SecurityReferences ID
         */
        private String name = "Authorization";

        /**
         * 鉴权传递的Header参数
         */
        private String keyName = "Authorization";

        private String passAs = "header";

        private List<AuthorizationScopeProperties> scopes = Collections.singletonList(new AuthorizationScopeProperties());

        private List<GrantProperties> grantTypes;

        private String pathRegex = "^.*$";
    }

    @Data
    public static class GrantProperties {

        private GrantEnum type;

        private String tokenRequestUrl;

        private String clientIdName;

        private String clientSecretName;

        private String tokenEndUrl;

        private String tokenName;

        private String loginEndUrl;

        private String tokenUrl;
    }

    @Data
    public static class AuthorizationScopeProperties {

        private String scope = "global";

        private String description = "accessEverything";
    }

    @Data
    public static class ApiInfoProperties {

        /**
         * 标题
         */
        private String title = ApiInfo.DEFAULT.getTitle();

        /**
         * 描述
         */
        private String description = ApiInfo.DEFAULT.getDescription();

        /**
         * 版本
         */
        private String version = ApiInfo.DEFAULT.getVersion();

        /**
         * 服务条款URL
         */
        private String termsOfServiceUrl = ApiInfo.DEFAULT.getTermsOfServiceUrl();

        /**
         * 联系信息
         */
        private ContactProperties contact = new ContactProperties();

        /**
         * 许可证
         */
        private String license = ApiInfo.DEFAULT.getLicense();

        /**
         * 许可证URL
         */
        private String licenseUrl = ApiInfo.DEFAULT.getLicenseUrl();
    }
}
